package com.buddies.lottery.data;

import android.text.TextUtils;

import com.blankj.utilcode.util.AppUtils;
import com.blankj.utilcode.util.DeviceUtils;
import com.blankj.utilcode.util.EncryptUtils;
import com.blankj.utilcode.util.NetworkUtils;
import com.blankj.utilcode.util.Utils;
import com.buddies.lottery.common.ConfigManager;
import com.tencent.bugly.crashreport.BuglyLog;

import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

import okhttp3.FormBody;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * 拦截网络请求，添加默认参数
 * Created by liuleigang on 2017/12/2.
 */

public class CommonIntercepter implements Interceptor {
    private static final Map<String, String> mParamsMap = new HashMap<>();
    private static final Map<String, String> mHeaderParamsMap = new HashMap<>();

    private String mRequestSalt;

    public CommonIntercepter() {
        initDefaultParams();
    }

    protected void initDefaultParams() {
        // 设置默认 Header
        mHeaderParamsMap.put("Content-Type", "application/json");
        mHeaderParamsMap.put("Accept", "application/json");

        // 设置默认参数
        mParamsMap.put("ver", AppUtils.getAppVersionName());
        mParamsMap.put("sys", "android_" + DeviceUtils.getSDKVersionName());
        mParamsMap.put("chn", com.buddies.lottery.utils.AppUtils.getChannel());// 渠道号
        mParamsMap.put("net", String.valueOf(NetworkUtils.getNetworkType().ordinal()));
        mParamsMap.put("did", com.buddies.lottery.utils.AppUtils.getDeviceID());
        mParamsMap.put("mod", DeviceUtils.getModel().replace(" ", ""));
        String country = Utils.getApp().getResources().getConfiguration().locale.getCountry();
        int lan = 2;
        if ("CN".equalsIgnoreCase(country)) {
            lan = 0;
        } else if ("TW".equalsIgnoreCase(country) || "HK".equalsIgnoreCase(country)) {
            lan = 1;
        }
        mParamsMap.put("lan", Integer.toString(lan));
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        return chain.proceed(genNewRequest(chain.request()));
    }

    /**
     * 拦截每个请求，添加默认参数，
     * 生成新的请求
     */
    private Request genNewRequest(Request oldRequest) { // 定制新的请求
        Request.Builder resBuilder = oldRequest.newBuilder();
        HttpUrl oldUrl = oldRequest.url();
        HttpUrl.Builder urlBuilder = oldUrl.newBuilder();

        // 添加统一的header
        if (mHeaderParamsMap.size() > 0) {
            for (Map.Entry<String, String> params : mHeaderParamsMap.entrySet()) {
                resBuilder.header(params.getKey(), params.getValue());
            }
        }

        // 添加动态改变的参数
        Map<String, String> queryParams = new HashMap<>(mParamsMap);
        queryParams.put("ts", Long.toString(System.currentTimeMillis()));

        String token = ConfigManager.getInstance().getToken();
        if (!TextUtils.isEmpty(token)) {
            queryParams.put("token", token);
        }

        for (int i = 0; i < oldUrl.querySize(); ++i) {
            urlBuilder.removeAllQueryParameters(oldUrl.queryParameterName(i));
            queryParams.put(oldUrl.queryParameterName(i), oldUrl.queryParameterValue(i));
        }

        Map<String, String> postParams = new HashMap<>();
        RequestBody requestBody = oldRequest.body();
        if (requestBody instanceof FormBody) {
            FormBody body = (FormBody) requestBody;
            for (int i = 0; i < body.size(); i++) {
//                postParams.put(body.encodedName(i), body.encodedValue(i));
                postParams.put(body.name(i), body.value(i));
            }
        }

        String newSign = genSign(queryParams, postParams, mRequestSalt);
        queryParams.put("sig", newSign.toLowerCase(Locale.CHINESE));

        for (Map.Entry<String, String> params : queryParams.entrySet()) {
            urlBuilder.addQueryParameter(params.getKey(), params.getValue());
        }
        resBuilder.url(urlBuilder.build());

//        String domain = NetWorkUtils.getDomain(oldRequest.url().toString());
//        String ip = OkhttpDns.getIpByHost(domain);
//        if (!TextUtils.isEmpty(domain) && !TextUtils.isEmpty(ip)) {
//            HttpDNSManager.instance().reportOK(domain, ip);
//        }
        return resBuilder.build();
    }

    /**
     * 动态生成签名信息
     */
    protected String genSign(Map<String, String> params, Map<String, String> postParams, String salt) {
        if (params == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        Object[] array;
        if (null != postParams && !postParams.isEmpty()) {
            array = postParams.keySet().toArray();
            if (array != null && array.length > 0) {
                Arrays.sort(array);// 默认升序排列，array为参数组成的数组

                for (Object k : array) {
                    String k_ = String.valueOf(k);
                    if (!"file".equals(k_) && !"sig".equals(k_)) {
                        String value = postParams.get(k);
                        sb.append(k_).append("").append(value);
                    }
                }
            }
        }
        array = params.keySet().toArray();
        if (array != null && array.length > 1) {
            Arrays.sort(array);// 默认升序排列，array为参数组成的数组

            for (Object k : array) {
                String k_ = String.valueOf(k);
                if (!"file".equals(k_) && !"sig".equals(k_)) {
                    String value = params.get(k);
                    sb.append(k_).append("").append(value);
                }
            }
        }

        String signData = sb.toString();
        BuglyLog.d("NetRequest", "sign data: " + signData);
        String sign = EncryptUtils.encryptMD5ToString(signData, salt);// key为客户端对应私钥
        BuglyLog.d("NetRequest", "sign result: " + sign);
        return sign;
    }

    public void setDefaultRequestParams(Map<String, String> params) {
        if (params != null) {
            mParamsMap.putAll(params);
        }
    }

    public void setDefaultRequestHeaders(Map<String, String> headers) {
        if (headers != null) {
            mHeaderParamsMap.putAll(headers);
        }
    }

    public void setRequestSalt(String salt) {
        mRequestSalt = salt;
    }
}
